package cqg.processor;

import java.io.IOException;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;

import org.w3c.dom.Document;

import cqg.CqgReport;

/**
 * Template Method for an implementation of Processor that use XPath to parse a code
 *  analysis report.
 *  <br><br>
 * @author Julio César Pérez Arques
 */
public abstract class XPathAbstractProcessor implements Processor {

	@Override
	public CqgReport process(String reportPath) throws IOException {
		Document document = buildDocument(reportPath);
		XPath xPath = buildXPath();
		
		CqgReport cqgReport = null;
		try {			
			cqgReport = parseCqgReport(document, xPath);
		} catch (Exception e) {
			throw new IllegalArgumentException("Error processing XML report", e);
		}
		
		return cqgReport;
	}
	
	/**
	 * Abstract method thar must parse the xml report to create a CqgReport using XPath
	 * @param document
	 * @param xPath
	 * @return
	 * @throws XPathExpressionException
	 */
	protected abstract CqgReport parseCqgReport(Document document, XPath xPath) throws XPathExpressionException;
	
	/**
	 * Returns the xml document created from the code analysis report
	 * @param reportPath
	 * @return
	 * @throws IOException
	 */
	protected Document buildDocument(String reportPath) throws IOException {
		Document document = null;
		DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
		try {
			DocumentBuilder builder = factory.newDocumentBuilder();
			document = builder.parse(reportPath);
		} catch (Exception e) {
			throw new IllegalStateException(e.getMessage(), e);
		}
		return document;
	}
	
	/**
	 * Returns the XPath object that will be used in parseCqgReport method
	 * @return
	 */
	protected XPath buildXPath() {
		XPathFactory xFactory = XPathFactory.newInstance();
		return xFactory.newXPath();
	}

}
